package ldh.serialize.io;

/**
 * Created by ldh on 2016/10/23.
 */
public class ByteBuf {

    private Integer size;
    private Integer readIdx = 0;
    private Integer writeIdx = 0;
    private byte[] bytes;

    public ByteBuf(byte[] bytes) {
        this.bytes = bytes;
        size = writeIdx = bytes.length;
    }

    public ByteBuf(Integer size) {
        this.size = size;
        bytes = new byte[size];
    }

    public byte readByte() {
        if (readIdx <= writeIdx) {
            return bytes[readIdx++];
        }
        throw new RuntimeException("read over");
    }

    public void writeBytes(byte[] bytes) {
        ensureSize(bytes.length);
        System.arraycopy(bytes, 0, this.bytes, writeIdx, bytes.length);
        writeIdx += bytes.length;
    }

    public void writeByte(byte bb) {
        ensureSize(1);
        bytes[writeIdx] = bb;
        writeIdx += 1;
    }

    public byte[] array() {
        byte[] rs = new byte[writeIdx - readIdx];
        System.arraycopy(bytes, readIdx, rs, 0, rs.length);
        return rs;
    }

    public void readBytes(byte[] bbs) {
        if (writeIdx - readIdx >= bbs.length) {
            System.arraycopy(bytes, readIdx, bbs, 0, bbs.length);
            readIdx += bbs.length;
            return;
        }
        throw new RuntimeException("read over");
    }

    public char readChar() {
        if (writeIdx - readIdx >= 1) {
            byte t = bytes[readIdx++];
            return (char)t;
        }
        throw new RuntimeException("read over");
    }

    private void ensureSize(int size) {
        if (this.size - writeIdx < size) {
            int lg = (int) (this.size * 1.5);
            byte[] newBytes = new byte[lg];
            System.arraycopy(this.bytes, 0, newBytes, 0, this.size);
            this.size = lg;
            this.bytes = newBytes;
        }
    }
}
